package com.miao.util.collection;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;

import java.util.*;

/**
 * Created by miao on 2015/4/13.
 */
public class Converter {

    public static void filter(Collection<Map> list, Set<String> set, String childKey) {
        if (list == null || list.size() == 0) return;
        for (Map map : list) {
            if (StringUtils.isNotBlank(childKey)) {
                Collection<Map> temp = (Collection<Map>) map.get(childKey);
                filter(temp, set, childKey);
            }
            for (Iterator itr = map.keySet().iterator(); itr.hasNext(); ) {
                String key = String.valueOf(itr.next());
                if (!set.contains(key)) {
                    itr.remove();
                }
            }
        }
    }

    /*
        参数1 list:目标列表
        参数2 defPidVal:从哪个id开始形成tree
        参数3 idKey:列表中Map对象的id的key
        参数4 pidKey:列表中Map对象的pid的key
        参数5 childKey:代表当前对象子的key
        参数6 filter:列表中每个Map对象需要输出的列,以"|"分隔
     */
    public static Collection<Map> List2Tree(Collection<Map> list, String defPidVal, String idKey, String pidKey, String childKey, String filter) {
        Collection<Map> coll = conver(list, defPidVal, idKey, pidKey, childKey);
        String[] ks = StringUtils.split(filter, "|");
        ks = ks == null ? new String[0] : ks;
        Set<String> set = new HashSet<String>();
        for (String k : ks) {
            if (StringUtils.isNotBlank(k)) {
                set.add(k);
            }
        }
        set.add(childKey);
        filter(coll, set, childKey);
        return coll;
    }

    private static Collection<Map> conver(Collection<Map> list, String defPidVal, String idKey, String pidKey, String childKey) {
        Collection<Map> root = new ArrayList<Map>();
        for (Map menu : list) {
            String val = MapUtils.getString(menu, pidKey);
            if (StringUtils.isBlank(val) || StringUtils.equals("0", val) || StringUtils.equals(val, defPidVal)) {
                root.add(menu);
            }
        }
        list.removeAll(root);
        mapping(list, root, idKey, pidKey, childKey);
        return root;
    }

    private static void mapping(Collection<Map> source, Collection<Map> list, String idKey, String pidKey, String childKey) {
        for (Map menu : list) {
            Set<Map> root = new LinkedHashSet<Map>();
            for (Map s : source) {
                if (StringUtils.equals(MapUtils.getString(s, pidKey, "-1"), MapUtils.getString(menu, idKey, "-2"))) {
                    root.add(s);
                }
            }
            menu.put(childKey, root);
            source.removeAll(root);
            mapping(source, (Collection) MapUtils.getObject(menu, childKey), idKey, pidKey, childKey);
        }
    }
}
